/*
 * 描          述:  <描述>
 * 修  改   人:  Administrator
 * 修改时间:  2019年6月8日
 * <修改描述:>
 */
package com.tx.core.mybatis.mapper;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tx.core.exceptions.util.AssertUtils;
import com.tx.core.paged.model.PagedList;
import com.tx.core.paged.model.impl.PagedListImpl;
import com.tx.core.util.TableInfoUtils;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;

import java.io.Serializable;
import java.util.List;

/**
 * 继承于Mybatis-plus实现的BaseMapper
 * 用以统一内部命名规范
 * 形成与之前代码生成相对统一，一致的dao层方法名暴露
 * 通过在接口中定义default方法实现雷同的命名暴露
 *
 * @param <T>
 * @param <ID>
 */
@Mapper
public interface MybatisBaseMapper<T, ID extends Serializable> extends BaseMapper<T> {

    /**
     * 保存实体类<br/>
     *
     * @param entity
     */
    default void save(T entity) {
        AssertUtils.notNull(entity, "entity is null.");

        //获取主键信息
        TableInfoUtils.TableColumnInfo pkci = TableInfoUtils.parsePKTableColumn(entity.getClass());
        BeanWrapper bw = PropertyAccessorFactory
                .forBeanPropertyAccess(entity);
        ID pkValue = (ID) bw.getPropertyValue(pkci.getPropertyName());

        if (ObjectUtil.isEmpty(pkValue)) {
            insert(entity);
        } else {
            Object resObj = findById(pkValue);
            if (resObj == null) {
                insert(entity);
            } else {
                updateById(entity);
            }
        }
    }

    /**
     * 根据主键查询对象实例<br/>
     *
     * @param id
     * @return
     */
    default T findById(ID id) {
        AssertUtils.notNull(id, "id is null.");

        T res = selectById(id);
        return res;
    }

    /**
     * 查询对象实例<br/>
     *
     * @param qw
     * @return
     */
    default T find(Wrapper<T> qw) {
        AssertUtils.notNull(qw, "queryWrapper不能为空.");

        T res = selectOne(qw);
        return res;
    }

    /**
     * 根据条件统计条数<br/>
     *
     * @param ew
     * @return
     */
    default Long count(Wrapper<T> ew) {
        Long res = selectCount(ew);
        return res;
    }

    /**
     * 查询列表<br/>
     *
     * @param ew
     * @return
     */
    default List<T> queryList(Wrapper<T> ew) {
        List<T> res = selectList(ew);
        return res;
    }

    /**
     * 查询分页列表
     *
     * @param ew
     * @param current
     * @param size
     * @return
     */
    default PagedList<T> queryPagedList(Wrapper<T> ew, long current, long size) {
        //long total = selectCount(queryWrapper);
        Page<T> resPage = selectPage(new Page<T>().of(current, size), ew);
        return PagedListImpl.of(resPage);
    }

    /**
     * 查询分页列表
     * 调用该方法不会自动调用count的方法自动获取total值
     *
     * @param ew
     * @param current
     * @param size
     * @return
     */
    default PagedList<T> queryPagedList(Wrapper<T> ew, long current, long size, long total) {
        Page<T> page = new PagedListImpl<>(current, size, total) {
            @Override
            public boolean searchCount() {
                return false;
            }
        };

        Page<T> resPage = selectPage(page, ew);
        return PagedListImpl.of(selectPage(page, ew));
    }

    /**
     * 根据条件判断条件对应内容是否存在
     *
     * @param queryWrapper
     * @return
     */
    default boolean exists(Wrapper<T> queryWrapper) {
        Long res = selectCount(queryWrapper);

        if (res != null && res.longValue() > 0) {
            return true;
        } else {
            return false;
        }
    }
}
